/*
 * Created on Mar 23, 2006
 *
 */
package org.mushroomdb.triggers;

import java.util.Iterator;

import org.mushroomdb.catalog.Register;
import org.mushroomdb.catalog.Table;
import org.mushroomdb.interceptor.AbstractInterceptor;
import org.mushroomdb.service.ServiceManager;

/**
 * @author mchiodi
 */
public class TriggersInterceptor extends AbstractInterceptor {
	
	private final static String BEFORE_INSERT_OPERATION = "beforeInsert"; //$NON-NLS-1$
	private final static String AFTER_INSERT_OPERATION = "afterInsert"; //$NON-NLS-1$
	private final static String BEFORE_UPDATE_OPERATION = "beforeUpdate"; //$NON-NLS-1$
	private final static String AFTER_UPDATE_OPERATION = "afterUpdate"; //$NON-NLS-1$
	private final static String BEFORE_DELETE_OPERATION = "beforeDelete"; //$NON-NLS-1$
	private final static String AFTER_DELETE_OPERATION = "afterDelete"; //$NON-NLS-1$

	private TriggersService triggersService;
	private ThreadLocal operation;

	/**
	 * Constructs the Triggers Interceptor.
	 */
	public TriggersInterceptor() {
		super();
		this.triggersService = (TriggersService) ServiceManager.getInstance().getService(TriggersService.class);
		this.operation = new ThreadLocal();
	}
	
	/**
	 * 
	 * @param operation
	 */
	private void register(String operation) {
		this.operation.set(operation);
	}
	
	/**
	 * 
	 * @param operation
	 * @return
	 */
	private boolean isRegistered(String operation) {
		return this.operation.get() != null;
	}
	
	/**
	 * 
	 * @param operation
	 */
	private void unRegister(String operation) {
		this.operation.set(null);
	}

	/**
	 * @see org.mushroomdb.interceptor.Interceptor#afterDelete(org.mushroomdb.catalog.Register, org.mushroomdb.catalog.Table)
	 */
	public void afterDelete(Register register, Table table) {
		if (!this.isRegistered(AFTER_DELETE_OPERATION)) {
			this.register(AFTER_DELETE_OPERATION);
			
			Iterator iterator = this.triggersService.getTriggers(table);
			while (iterator.hasNext()) {
				Trigger trigger = (Trigger) iterator.next();
				if (trigger.getType() == Trigger.AFTER) {
					if (trigger.getOperation() == Trigger.DLETE_OPERATION) {
						trigger.fire();
					}
				}
			}
			
			this.unRegister(AFTER_DELETE_OPERATION);
		}
	}
	
	/**
	 * @see org.mushroomdb.interceptor.Interceptor#afterInsert(org.mushroomdb.catalog.Register, org.mushroomdb.catalog.Table)
	 */
	public void afterInsert(Register register, Table table) {
		if (!this.isRegistered(AFTER_INSERT_OPERATION)) {
			this.register(AFTER_INSERT_OPERATION);
			
			Iterator iterator = this.triggersService.getTriggers(table);
			while (iterator.hasNext()) {
				Trigger trigger = (Trigger) iterator.next();
				if (trigger.getType() == Trigger.AFTER) {
					if (trigger.getOperation() == Trigger.INSERT_OPERATION) {
						trigger.fire();
					}
				}
			}
			
			this.unRegister(AFTER_INSERT_OPERATION);
		}
	}
	
	/**
	 * @see org.mushroomdb.interceptor.Interceptor#afterUpdate(org.mushroomdb.catalog.Register, int, java.lang.Object, org.mushroomdb.catalog.Table)
	 */
	public void afterUpdate(Register register, int columnIndex, Object value, Table table) {
		if (!this.isRegistered(AFTER_UPDATE_OPERATION)) {
			this.register(AFTER_UPDATE_OPERATION);
				
			Iterator iterator = this.triggersService.getTriggers(table);
			while (iterator.hasNext()) {
				Trigger trigger = (Trigger) iterator.next();
				if (trigger.getType() == Trigger.AFTER) {
					if (trigger.getOperation() == Trigger.UPDATE_OPERATION) {
						trigger.fire();
					}
				}
			}
			
			this.unRegister(AFTER_UPDATE_OPERATION);
		}
	}
	
	/**
	 * @see org.mushroomdb.interceptor.Interceptor#beforeDelete(org.mushroomdb.catalog.Register, org.mushroomdb.catalog.Table)
	 */
	public void beforeDelete(Register register, Table table) {
		if (!this.isRegistered(BEFORE_DELETE_OPERATION)) {
			this.register(BEFORE_DELETE_OPERATION);
				
			Iterator iterator = this.triggersService.getTriggers(table);
			while (iterator.hasNext()) {
				Trigger trigger = (Trigger) iterator.next();
				if (trigger.getType() == Trigger.BEFORE) {
					if (trigger.getOperation() == Trigger.DLETE_OPERATION) {
						trigger.fire();
					}
				}
			}
			
			this.unRegister(BEFORE_DELETE_OPERATION);
		}
	}
	
	/**
	 * @see org.mushroomdb.interceptor.Interceptor#beforeInsert(org.mushroomdb.catalog.Register, org.mushroomdb.catalog.Table)
	 */
	public void beforeInsert(Register register, Table table) {
		if (!this.isRegistered(BEFORE_INSERT_OPERATION)) {
			this.register(BEFORE_INSERT_OPERATION);
			
			Iterator iterator = this.triggersService.getTriggers(table);
			while (iterator.hasNext()) {
				Trigger trigger = (Trigger) iterator.next();
				if (trigger.getType() == Trigger.BEFORE) {
					if (trigger.getOperation() == Trigger.INSERT_OPERATION) {
						trigger.fire();
					}
				}
			}
			
			this.unRegister(BEFORE_INSERT_OPERATION);
		}
	}
	
	/**
	 * @see org.mushroomdb.interceptor.Interceptor#beforeUpdate(org.mushroomdb.catalog.Register, int, java.lang.Object, org.mushroomdb.catalog.Table)
	 */
	public void beforeUpdate(Register register, int columnIndex, Object value, Table table) {
		if (!this.isRegistered(BEFORE_UPDATE_OPERATION)) {
			this.register(BEFORE_UPDATE_OPERATION);
				
			Iterator iterator = this.triggersService.getTriggers(table);
			while (iterator.hasNext()) {
				Trigger trigger = (Trigger) iterator.next();
				if (trigger.getType() == Trigger.BEFORE) {
					if (trigger.getOperation() == Trigger.UPDATE_OPERATION) {
						trigger.fire();
					}
				}
			}
			
			this.unRegister(BEFORE_UPDATE_OPERATION);
		}
	}
}
